#ifndef TCP_SOCKET_H
#define TCP_SOCKET_H

#include <QtNetwork>

#include "tcp_agreement.h"
#include <QByteArray>
#include <QMutex>

class TcpSocket : public QObject
{
    Q_OBJECT
public:
    //explicit TcpSocket(QTcpSocket *socket,  qintptr socketDescriptor, QObject *parent = 0);
     explicit TcpSocket(qintptr socketDescriptor, QObject *parent = 0);

    ~TcpSocket();

    QTcpSocket *m_socket;

private:

    QString m_ip;
    int m_port;
    qintptr m_socketDescriptor;

    //包头
    qint64 m_frameHeadLength = 12;
    //已收到的字节数
    qint64 m_totalBytes = 0;//要接受数据的总大小
    qint64 m_receivedBytes = 0;//已接受的数据
    QByteArray m_infoBlock;//帧体内容（除去帧头的所有内容）
    QByteArray m_tmpBlock;//临时存储的数据

    QByteArray m_frameHead;//帧头
    QByteArray m_frameContent;//帧体
    QByteArray m_frameTail;//帧尾

    QByteArray m_command;//命令
    QByteArray m_Check;//异或校验
    QByteArray m_length;//长度
    QByteArray m_serialNumber;//序列号
    CommondNumber m_commandNumber;//发送时，填充命令使用

    //心跳统计（5秒刷新），如果3次没有收到，就自动断开和客户端的连接
    QTimer* m_heartBeatTimingStatisticsTimer;
    //是否创建过计时统计
    bool m_isCreateheartBeatTimingStatisticsTimer = false;
    //统计数量
    int m_heartBeatTimingStatisticsTimerCount = 3;

    QMutex m_heartBeatTimingStatisticsTimerCountMutex;


public:
    /**
     * @brief 得到IP
     * @return
     */
    QString getIP() const;
    /**
     * @brief 得到端口号
     * @return
     */
    int getPort()   const;
    /**
     * @brief 得到套接字描述符
     * @return
     */
    qintptr getSocketDescriptor();

    /**
     * @brief getOrCode：得到异或校验码
     * @param data
     * @return
     */
    QString getOrCode(const QByteArray &data);

    //处理要发送的数据
    QByteArray dealSendData(CommondNumber command, const QString &data);

    QByteArray dealSendData2(const QString &data);

    QByteArray dealSendData3(CommondNumber command, const QByteArray data);

    void dealRecieveData(QByteArray command, QByteArray frameContent);

private slots:
    /**
     * @brief 断开连接
     */
    void disconnected();
    /**
     * @brief 读取数据
     */
    void readData();

signals:
    /**
     * @brief 发送数据
     * @param data
     */
    void sendSocketData(const QString &ip, int port, const QByteArray data);

    /**
     * @brief 主界面发送数据
     * @param data
     */
    void sendSocketData(const QString &ip, int port, CommondNumber command, const QByteArray data);

    /**
     * @brief receiveData:发送处理接收到的数据
     * @param ip
     * @param port
     * @param data
     */
    void receiveData(const QString &ip, int port, QByteArray data);

    /**
     * @brief clientDisconnected：客户端断开连接
     * @param socketDescriptor
     */
    void clientDisconnected(qintptr socketDescriptor);

    /**
     * @brief sendLowerComputerChangeInformation：发送下位机改变的数据
     * @param command
     * @param data
     */
    void sendLowerComputerChangeInformation(CommondNumber command, const QByteArray data);

    void conveyEquipmentStatusType(int);

    void sendHeartBeatTimingDisconnected();

public slots:
    /**
     * @brief 发送数据
     * @param data
     */
    void sendData(QByteArray data);
    /**
     * @brief 套接字断开连接
     */
    void abort();

    void initializeTcpSocketFunction();

private:
    QString byteArrayToHexStr(const QByteArray &data);

};


#endif // TCP_SOCKET_H
